<!-- 
  * 安全事件基础信息表 - ES查询版本
  *
  * @Author:    chenyuqiang
  * @Date:      2025-08-24 20:37:14
  * @Copyright  1.0
-->
<template>
    <!---------- 查询表单form begin ----------->
    <a-form class="smart-query-form" layout="inline">
        <a-row class="smart-query-form-row" :gutter="16">
            <!-- KQL查询框 -->
            <a-col :span="24">
                <div class="kql-search-container">
                    <div class="search-row">
                        <div class="kql-input-wrapper" @click="focusInput">
                            <div class="kql-input-container">
                                <textarea
                                    ref="kqlInput"
                                    v-model="searchInput"
                                    class="kql-input"
                                    placeholder="输入查询条件"
                                    @input="handleInput"
                                    @keydown="handleKeyDown"
                                    @focus="handleFocus"
                                    @blur="handleBlur"
                                    rows="1"
                                ></textarea>
                            </div>
                            
                            <!-- 智能提示下拉框 -->
                            <div v-if="showSuggestions" class="kql-suggestions">
                                <div v-if="suggestions.length > 0" class="suggestions-list">
                                    <div
                                        v-for="(suggestion, index) in suggestions"
                                        :key="index"
                                        :class="['suggestion-item', { active: currentSuggestionIndex === index }]"
                                        @mousedown.prevent="selectSuggestion(suggestion)"
                                        @mouseover="currentSuggestionIndex = index"
                                    >
                                        <template v-if="suggestion.type === 'field'">
                                            <span class="suggestion-icon">📋</span>
                                            <span class="suggestion-text">{{ suggestion.value }}</span>
                                            <span class="suggestion-type">{{ suggestion.displayName }}</span>
                                        </template>
                                        <template v-else-if="suggestion.type === 'operator'">
                                            <span class="suggestion-icon">⚡</span>
                                            <span class="suggestion-text">{{ suggestion.value }}</span>
                                            <span class="suggestion-type">{{ suggestion.description }}</span>
                                        </template>
                                        <template v-else-if="suggestion.type === 'value'">
                                            <span class="suggestion-icon">📝</span>
                                            <span class="suggestion-text">{{ suggestion.value }}</span>
                                            <span class="suggestion-type">值</span>
                                        </template>
                                    </div>
                                </div>
                                <div v-else class="no-suggestions">
                                    无匹配建议
                                </div>
                            </div>
                        </div>
                        
                        <div class="time-range-container">
                            <a-range-picker
                                v-model:value="timeRange"
                                :ranges="timePresets"
                                show-time
                                format="YYYY-MM-DD HH:mm:ss"
                                :placeholder="['开始时间', '结束时间']"
                                @change="handleTimeChange"
                                @openChange="handleOpenChange"
                                :disabled-date="disabledDate"
                                class="time-range-picker"
                            >
                                <template #suffixIcon><ClockCircleOutlined /></template>
                            </a-range-picker>
                        </div>

                        <div class="log-type-container">
                            <a-select
                                :value="queryForm.opnum"
                                placeholder="请选择日志类型"
                                allowClear
                                @change="(value) => { queryForm.opnum = value; onSearch(); }"
                                style="width: 150px;"
                                :options="logTypeOptions"
                            />
                        </div>

                        <!-- 添加聚合字段多选下拉框 -->
                        <div class="aggregation-container">
                            <a-select
                                v-model:value="queryForm.aggregationFields"
                                mode="multiple"
                                placeholder="请选择聚合字段"
                                allowClear
                                style="width: 300px;"
                                :options="aggregationOptions"
                                @change="onSearch"
                            />
                        </div>

                        <!-- <div class="index-container">
                            <a-select
                                v-model:value="queryForm.indexName"
                                placeholder="请选择索引"
                                allowClear
                                @change="onSearch"
                                style="width: 200px;"
                                show-search
                                :filter-option="filterIndexOption"
                            >
                                <a-select-option value="">默认索引</a-select-option>
                                <a-select-option value="security-events-2025.01">security-events-2025.01</a-select-option>
                                <a-select-option value="security-events-2025.02">security-events-2025.02</a-select-option>
                                <a-select-option value="security-events-2025.03">security-events-2025.03</a-select-option>
                                <a-select-option value="firewall-logs-2025.01">firewall-logs-2025.01</a-select-option>
                                <a-select-option value="ids-logs-2025.01">ids-logs-2025.01</a-select-option>
                                <a-select-option value="waf-logs-2025.01">waf-logs-2025.01</a-select-option>
                            </a-select>
                        </div> -->

                        <div class="button-group">
                            <a-button type="primary" @click="onSearch">
                                <template #icon><SearchOutlined /></template>
                                查询
                            </a-button>
                            <a-button @click="resetQuery" class="smart-margin-left10">
                                <template #icon><ReloadOutlined /></template>
                                重置
                            </a-button>
                            <a-button type="link" @click="showHelp = true">
                                <template #icon><QuestionCircleOutlined /></template>
                                查询帮助
                            </a-button>
                        </div>
                    </div>
                </div>
            </a-col>
        </a-row>
    </a-form>

    <!-- 帮助弹窗 -->
    <a-modal
        v-model:visible="showHelp"
        title="KQL查询语法帮助"
        width="600px"
        :footer="null"
    >
        <pre style="white-space: pre-wrap; font-family: monospace;">{{ searchHelpText }}</pre>
    </a-modal>

    <!---------- 查询表单form end ----------->

    <a-card size="small" :bordered="false" :hoverable="true">
        <!---------- 表格操作行 begin ----------->
        <a-row class="smart-table-btn-block">
            <div class="smart-table-operate-block">
                <a-tag color="blue">ES数据源</a-tag>
                <a-tag color="green">实时查询</a-tag>
                <span class="smart-margin-left10">
                    共查询到 <a-tag color="red">{{ total }}</a-tag> 条安全事件
                </span>
                <!-- <a-button
                    type="link"
                    size="small"
                    @click="getClusterStatus"
                    class="smart-margin-left10"
                >
                    <ReloadOutlined /> 检查ES状态
                </a-button>
                <a-button
                    type="link"
                    size="small"
                    @click="getIndexInfo"
                    class="smart-margin-left10"
                >
                    <SearchOutlined /> 索引信息
                </a-button> -->
            </div>
            <div class="smart-table-setting-block">
                <a-popover 
                    placement="bottomRight" 
                    trigger="click"
                    overlayClassName="column-setting-popover"
                >
                    <template #content>
                        <div class="column-setting-content">
                            <div class="column-setting-header">
                                <span>列展示</span>
                                <a-button type="link" size="small" @click="resetColumns">重置</a-button>
                            </div>
                            <a-divider style="margin: 8px 0" />
                            <div class="column-setting-list">
                                <a-checkbox-group v-model:value="checkedColumns">
                                    <div v-for="col in columns" :key="col.dataIndex" class="column-item">
                                        <a-checkbox 
                                            :value="col.dataIndex"
                                            :disabled="col.dataIndex === 'eventId' || col.dataIndex === 'operation'"
                                        >
                                            {{ col.title }}
                                        </a-checkbox>
                                    </div>
                                </a-checkbox-group>
                            </div>
                        </div>
                    </template>
                    <a-button type="link">
                        <template><SettingOutlined /></template>
                        列设置
                    </a-button>
                </a-popover>
                <TableOperator v-model="columns" :tableId="null" :refresh="refreshData" />
            </div>
        </a-row>
        <!---------- 表格操作行 end ----------->

        <!---------- 表格 begin ----------->
        <a-table
            size="small"
            :scroll="{ x: 2000, y: 600 }"
            :dataSource="tableData"
            :columns="visibleColumns"
            rowKey="eventId"
            bordered
            :loading="tableLoading"
            :pagination="false"
            :row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
            :resizable="true"
            @resizeColumn="handleResize"
        >
            <template #bodyCell="{ text, record, column }">
                <!-- 危险等级显示 -->
                <template v-if="column.dataIndex === 'severity'">
                    <a-tag :color="getSeverityColor(text)">
                        {{ getSeverityText(text) }}
                    </a-tag>
                </template>

                <!-- 事件类型显示 -->
                <template v-if="column.dataIndex === 'eventType'">
                    <a-tag color="blue">{{ text }}</a-tag>
                </template>

                <!-- 威胁分类显示 -->
                <template v-if="column.dataIndex === 'threatCategory'">
                    <a-tag color="red" v-if="text">{{ text }}</a-tag>
                    <span v-else>-</span>
                </template>

                <!-- 攻击结果显示 -->
                <template v-if="column.dataIndex === 'attackResult'">
                    <a-tag :color="text === '成功' ? 'red' : 'orange'" v-if="text">{{ text }}</a-tag>
                    <span v-else>-</span>
                </template>

                <!-- IP地址显示 -->
                <template v-if="['srcIp', 'dstIp', 'deviceIp'].includes(column.dataIndex)">
                    <a-tag color="geekblue" v-if="text">{{ text }}</a-tag>
                    <span v-else>-</span>
                </template>

                <!-- 端口显示 -->
                <template v-if="['srcPort', 'dstPort'].includes(column.dataIndex)">
                    <a-tag color="cyan" v-if="text">{{ text }}</a-tag>
                    <span v-else>-</span>
                </template>

                <!-- 状态码显示 -->
                <template v-if="column.dataIndex === 'reqStatus'">
                    <a-tag :color="getStatusColor(text)" v-if="text">{{ text }}</a-tag>
                    <span v-else>-</span>
                </template>

                <!-- 协议显示 -->
                <template v-if="column.dataIndex === 'protocol'">
                    <a-tag color="purple" v-if="text && typeof text === 'string'">{{ text.toUpperCase() }}</a-tag>
                    <span v-else>-</span>
                </template>

                <!-- 请求方法显示 -->
                <template v-if="column.dataIndex === 'reqMethod'">
                    <a-tag :color="getMethodColor(text)" v-if="text && typeof text === 'string'">{{ text.toUpperCase() }}</a-tag>
                    <span v-else>-</span>
                </template>

                <!-- 威胁指标显示 -->
                <template v-if="column.dataIndex === 'threatIndicators'">
                    <span v-if="text">{{ typeof text === 'object' ? JSON.stringify(text) : (text || '-') }}</span>
                    <span v-else>-</span>
                </template>

                <!-- 文件大小显示 -->
                <template v-if="column.dataIndex === 'fileSize'">
                    <span v-if="text">{{ formatFileSize(text) }}</span>
                    <span v-else>-</span>
                </template>

                <!-- 时间戳显示 -->
                <template v-if="['timestamp', 'eventTime', 'reciveTime'].includes(column.dataIndex)">
                    <span v-if="text">{{ formatTimestamp(text) }}</span>
                    <span v-else>-</span>
                </template>

                <!-- 操作列 -->
                <template v-if="column.dataIndex === 'operation'">
                    <div class="smart-table-operate">
                        <a-button @click="showDetail(record)" type="link">详情</a-button>
                        <a-button 
                            @click="handleSoarDisposal(record)" 
                            type="link"
                            :loading="record.soarLoading || false"
                        >
                            SOAR处置
                        </a-button>
                    </div>
                </template>
            </template>
        </a-table>
        <!---------- 表格 end ----------->

        <div class="smart-query-table-page">
            <a-pagination
                showSizeChanger
                showQuickJumper
                show-less-items
                :pageSizeOptions="PAGE_SIZE_OPTIONS"
                :defaultPageSize="queryForm.pageSize"
                v-model:current="queryForm.pageNum"
                v-model:pageSize="queryForm.pageSize"
                :total="total"
                @change="queryData"
                @showSizeChange="queryData"
                :show-total="(total) => `共${total}条安全事件`"
            />
        </div>

        <!-- 详情弹窗 -->
        <EventBaseDetail ref="detailRef" />

    </a-card>
</template>
<script setup>
    import { reactive, ref, onMounted, nextTick, computed, watch } from 'vue';
    import { message } from 'ant-design-vue';
    import dayjs from 'dayjs';
    import { SmartLoading } from '/@/components/framework/smart-loading';
    import { eventBaseEsApi } from '/@/api/business/event-base/event-base-es-api';
    import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
    import { smartSentry } from '/@/lib/smart-sentry';
    //import TableOperator from '/@/components/support/table-operator/index.vue';
    import EventBaseDetail from './event-base-detail.vue';
    import { SearchOutlined, ReloadOutlined, ClockCircleOutlined, SettingOutlined, QuestionCircleOutlined } from '@ant-design/icons-vue';
    
    // ---------------------------- 表格列宽调整相关 ----------------------------
    const COLUMN_WIDTH_STORAGE_KEY = 'event-base-column-widths';

    // 处理列宽调整
    const handleResize = (width, column) => {
        const targetColumn = columns.value.find(col => col.dataIndex === column.dataIndex);
        if (targetColumn) {
            targetColumn.width = width;
            // 保存到本地存储
            const widths = JSON.parse(localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY) || '{}');
            widths[column.dataIndex] = width;
            localStorage.setItem(COLUMN_WIDTH_STORAGE_KEY, JSON.stringify(widths));
        }
    };

    // 从本地存储加载列宽
    const loadColumnWidths = () => {
        const savedWidths = JSON.parse(localStorage.getItem(COLUMN_WIDTH_STORAGE_KEY) || '{}');
        columns.value.forEach(col => {
            if (savedWidths[col.dataIndex]) {
                col.width = savedWidths[col.dataIndex];
            }
        });
    };

    // ---------------------------- 表格列定义 ----------------------------
    const columns = ref([
        // 基础元数据
        {
            title: '事件ID',
            dataIndex: 'eventId',
            width: 120,
            ellipsis: true,
            fixed: 'left',
            resizable: true,
        },
        {
            title: 'ES ID',
            dataIndex: 'esId',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '入库时间',
            dataIndex: 'timestamp',
            width: 160,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '事件时间',
            dataIndex: 'eventTime',
            width: 160,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '接收时间',
            dataIndex: 'reciveTime',
            width: 160,
            ellipsis: true,
            resizable: true,
        },
        // 事件基本信息
        {
            title: '事件类型',
            dataIndex: 'eventType',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '事件名称',
            dataIndex: 'eventName',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '事件规则',
            dataIndex: 'eventRule',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '危险等级',
            dataIndex: 'severity',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '日志来源',
            dataIndex: 'name',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '详细信息',
            dataIndex: 'detailInfo',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        // 设备和资产信息
        {
            title: '设备名称',
            dataIndex: 'deviceName',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '设备IP',
            dataIndex: 'deviceIp',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '攻击数据包',
            dataIndex: 'attackPackets',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '源CMDB名称',
            dataIndex: 'srcCmdbName',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '目标CMDB名称',
            dataIndex: 'dstCmdbName',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        // 源端点信息
        {
            title: '源IP',
            dataIndex: 'srcIp',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '源类型',
            dataIndex: 'srcType',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '源端口',
            dataIndex: 'srcPort',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '源主机名',
            dataIndex: 'srcHostname',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '源MAC',
            dataIndex: 'srcMac',
            width: 130,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '源负责人',
            dataIndex: 'srcLeader',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '源安全域',
            dataIndex: 'srcSecurityDomains',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        // 目标端点信息
        {
            title: '目标IP',
            dataIndex: 'dstIp',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '目标类型',
            dataIndex: 'dstType',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '目标端口',
            dataIndex: 'dstPort',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '目标主机名',
            dataIndex: 'dstHostname',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '目标负责人',
            dataIndex: 'dstLeader',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '目标安全域',
            dataIndex: 'dstSecurityDomains',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        // 网络协议信息
        {
            title: '协议',
            dataIndex: 'protocol',
            width: 80,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '请求方法',
            dataIndex: 'reqMethod',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '请求URL',
            dataIndex: 'reqUrl',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        {
            title: 'Referer',
            dataIndex: 'reqReferer',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '状态码',
            dataIndex: 'reqStatus',
            width: 80,
            ellipsis: true,
            resizable: true,
        },
        {
            title: 'User-Agent',
            dataIndex: 'reqUserAgent',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '请求主机',
            dataIndex: 'reqHost',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '请求头',
            dataIndex: 'reqHeader',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '请求体',
            dataIndex: 'reqBody',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        {
            title: 'X-Forwarded-For',
            dataIndex: 'reqxff',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: 'Cookie',
            dataIndex: 'reqCookie',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '日志类型',
            dataIndex: 'logType',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '查询参数',
            dataIndex: 'queryString',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '请求开始时间',
            dataIndex: 'reqStartTime',
            width: 160,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '请求结束时间',
            dataIndex: 'reqEndTime',
            width: 160,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '返回头',
            dataIndex: 'respHeader',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        // 威胁信息
        {
            title: '威胁分类',
            dataIndex: 'threatCategory',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '威胁特征',
            dataIndex: 'threatSignature',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '威胁指标',
            dataIndex: 'threatIndicators',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '攻击类型',
            dataIndex: 'attackType',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '攻击结果',
            dataIndex: 'attackResult',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '攻击阶段',
            dataIndex: 'superType',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '攻击载荷',
            dataIndex: 'payload',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        // 规则告警信息
        {
            title: '规则名称',
            dataIndex: 'ruleAlertName',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '告警批次',
            dataIndex: 'ruleBatch',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '威胁等级',
            dataIndex: 'ruleAlertlevel',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '攻击链',
            dataIndex: 'ruleAlertLinks',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '告警结果',
            dataIndex: 'ruleAlertResult',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '告警描述',
            dataIndex: 'ruleAlertReason',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '处置建议',
            dataIndex: 'ruleAlertDisposal',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '规则代码',
            dataIndex: 'ruleCode',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '规则白名单',
            dataIndex: 'whiteRuleEffect',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        // 系统信息
        {
            title: '设备操作系统',
            dataIndex: 'deviceos',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '连接方式',
            dataIndex: 'cType',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '原始日志',
            dataIndex: 'rawLog',
            width: 200,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '安全设备处置结果',
            dataIndex: 'blocked',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: 'SOAR处置结果',
            dataIndex: 'action',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '分组数量',
            dataIndex: 'groupCount',
            width: 100,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '分组键值',
            dataIndex: 'groupKeys',
            width: 150,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '白名单规则',
            dataIndex: 'whiteRuleEffect',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        {
            title: '记录名称',
            dataIndex: 'recname',
            width: 120,
            ellipsis: true,
            resizable: true,
        },
        // 操作列
        {
            title: '操作',
            dataIndex: 'operation',
            fixed: 'right',
            width: 120,
            resizable: true,
        }
    ]);

    // ---------------------------- 查询数据表单和方法 ----------------------------
    // 日志类型映射
    const logTypeMap = {
        1: '原始日志',
        2: '原始告警', 
        3: '白名单告警',
        4: '异常记录'
    };

    // 日志类型选项
    const logTypeOptions = [
        { value: 1, label: '原始日志' },
        { value: 2, label: '原始告警' },
        { value: 3, label: '白名单告警' },
        { value: 4, label: '异常记录' }
    ];

    const queryFormState = {
        pageNum: 1,
        pageSize: 20,
        eventTimeBegin: dayjs().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:ss'),  // 默认最近1小时开始时间
        eventTimeEnd: dayjs().format('YYYY-MM-DD HH:mm:ss'),    // 默认当前时间结束
        eventType: undefined,
        severity: undefined,
        srcIp: '',
        dstIp: '',
        threatCategory: undefined,
        keywords: '',
        protocol: undefined,
        opnum: 1, // 默认选择原始日志，对应后端opnum=1
        geoCountry: undefined,
        indexName: '',  // 索引名称
        aggregationFields: [], // 添加聚合字段数组
    };

    // 查询表单form
    const queryForm = reactive({ ...queryFormState });
    
    // 时间范围相关
    const timeRange = ref([dayjs().subtract(1, 'hour'), dayjs()]);  // 默认选择最近1小时
    // 时间预设
    const timePresets = {
        '最近1小时': [dayjs().subtract(1, 'hour'), dayjs()],
        '最近24小时': [dayjs().subtract(24, 'hour'), dayjs()],
        '最近7天': [dayjs().subtract(7, 'day'), dayjs()],
        '最近30天': [dayjs().subtract(30, 'day'), dayjs()],
        '最近90天': [dayjs().subtract(90, 'day'), dayjs()],
    };

    // 处理时间范围变化
    function handleTimeChange(dates, dateStrings) {
        if (dates) {
            // 更新时间范围显示
            timeRange.value = dates;
            // 转换为后端所需的格式
            queryForm.eventTimeBegin = dates[0].format('YYYY-MM-DD HH:mm:ss');
            queryForm.eventTimeEnd = dates[1].format('YYYY-MM-DD HH:mm:ss');
        } else {
            timeRange.value = null;
            queryForm.eventTimeBegin = '';
            queryForm.eventTimeEnd = '';
        }
        queryData();
    }

    // 处理日期选择器打开/关闭
    function handleOpenChange(open) {
        if (!open && !timeRange.value) {
            queryForm.eventTimeBegin = '';
            queryForm.eventTimeEnd = '';
        }
    }

    // 禁用日期
    function disabledDate(current) {
        return current && current > dayjs().endOf('day');
    }

    // 表格加载loading
    const tableLoading = ref(false);
    // 表格数据
    const tableData = ref([]);
    // 总数
    const total = ref(0);
    // 选中的行
    const selectedRowKeyList = ref([]);

    // 字段配置
    const fieldConfigs = ref({});
    // 搜索输入
    const searchInput = ref('');
    // 是否显示建议
    const showSuggestions = ref(false);
    // 当前选中的建议索引
    const currentSuggestionIndex = ref(0);
    // 建议列表
    const suggestions = ref([]);
    // 输入框引用
    const kqlInput = ref(null);

    // 列设置相关
    const STORAGE_KEY = 'event-base-checked-columns';
    const defaultColumnKeys = [
        // 基础元数据
        'eventId', 'esId', 'timestamp', 'eventTime', 'reciveTime',
        
        // 事件基本信息
        'eventType', 'eventName', 'eventRule', 'severity', 'name',
        
        // 设备和资产信息
        'deviceName', 'deviceIp', 'attackPackets',
        'dstCmdbName', 'srcCmdbName',
        'srcSecurityDomains', 'dstSecurityDomains',
        
        // 源端点信息
        'srcIp', 'srcType', 'srcPort', 'srcHostname', 'srcMac',
        
        // 目标端点信息
        'dstIp', 'dstType', 'dstPort', 'dstHostname',
        
        // 网络协议信息
        'protocol', 'reqMethod', 'reqUrl', 'reqStatus',
        
        // 威胁信息
        'threatCategory', 'threatSignature', 'attackType', 'attackResult',
        'superType', 'payload',
        
        // 规则告警信息
        'ruleAlertName', 'ruleAlertlevel', 'ruleAlertResult',
        'ruleBatch', 'ruleAlertLinks', 'rulAlertReson',
        
        // 操作列
        'operation'
    ];

    // 从localStorage读取或使用默认值
    const savedColumns = localStorage.getItem(STORAGE_KEY);
    const checkedColumns = ref(savedColumns ? JSON.parse(savedColumns) : defaultColumnKeys);

    // 监听checkedColumns变化并保存到localStorage
    watch(checkedColumns, (newVal) => {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(newVal));
    }, { deep: true });

    // 计算当前显示的列
    const visibleColumns = computed(() => {
        return columns.value.filter(col => 
            checkedColumns.value.includes(col.dataIndex) || 
            col.dataIndex === 'eventId' || 
            col.dataIndex === 'operation'
        );
    });

    // 重置列设置
    function resetColumns() {
        checkedColumns.value = defaultColumnKeys;
    }

    // 构建时间范围查询条件
    function buildTimeRangeQuery() {
        if (timeRange.value && timeRange.value.length === 2) {
            return {
                range: {
                    '@timestamp': {
                        gte: timeRange.value[0].utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'),
                        lte: timeRange.value[1].utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]')
                    }
                }
            };
        }
        return null;
    }

    // 获取字段配置
    async function getFieldConfigs() {
        try {
            const result = await eventBaseEsApi.getFieldConfigs();
            if (result.ok) {
                fieldConfigs.value = result.data;
            } else {
                message.error('获取字段配置失败：' + result.msg);
             
                }
            }
         catch (e) {
            smartSentry.captureError(e);
            message.error('获取字段配置失败：' + e.message);
        }
    }

    // 查询帮助文本
    const searchHelpText = `KQL查询语法帮助

1. 基本语法
   字段名 运算符 值 [AND|OR] [字段名 运算符 值]...

2. 支持的运算符
   : 或 ==    精确匹配（等于）
   !=         不等于
   >          大于
   >=         大于等于
   <          小于
   <=         小于等于
   *          通配符匹配（包含）
   exists     字段存在
   not exists 字段不存在
   in         在列表中 (例如: status in [200,201,202])
   not in     不在列表中
   contains   包含
   not contains 不包含

3. 示例
   - 精确匹配：event_type : "ids_alert"
   - 不等于：severity != "high"
   - 通配符：event_type * "ids_"
   - 数值比较：severity > 3
   - 列表匹配：status in [200,201,202]
   - 组合查询：event_type : "ids_alert" AND severity > 3
   - 包含查询：message contains "error"
   - 字段存在：ip exists
   
4. 注意事项
   - 字符串值建议使用引号包裹
   - 列表值使用方括号 [] 包裹，值之间用逗号分隔
   - 多个条件可以用 AND 或 OR 连接
   - 支持使用括号 () 来分组条件
`;

    // 添加帮助按钮和弹窗
    const showHelp = ref(false);

    // 在template中添加帮助按钮
    // 在.kql-search-container的button-group中添加：
    /*
    <a-button type="link" @click="showHelp = true">
        <template #icon><QuestionCircleOutlined /></template>
        查询帮助
    </a-button>

    <!-- 帮助弹窗 -->
    <a-modal
        v-model:visible="showHelp"
        title="KQL查询语法帮助"
        width="600px"
        :footer="null"
    >
        <pre style="white-space: pre-wrap; font-family: monospace;">{{ searchHelpText }}</pre>
    </a-modal>
    */

    // 选择建议
    function selectSuggestion(suggestion) {
        const cursorPosition = kqlInput.value.selectionStart;
        const inputValue = searchInput.value;
        const beforeCursor = inputValue.slice(0, cursorPosition);
        const afterCursor = inputValue.slice(cursorPosition);
        const tokens = beforeCursor.split(/\s+/);
        const lastToken = tokens[tokens.length - 1];

        let replacement = suggestion.value;
        // 如果是运算符，添加空格
        if (suggestion.type === 'operator') {
            replacement = `${replacement} `;
            // 选择运算符后关闭下拉框
            showSuggestions.value = false;
        } else if (suggestion.type === 'field') {
            // 如果是字段，添加空格并显示运算符下拉
            replacement = `${replacement} `;
            nextTick(() => {
                showOperatorSuggestions(suggestion.value);
            });
        }

        // 替换当前token
        const newValue = lastToken ?
            inputValue.slice(0, cursorPosition - lastToken.length) + replacement + afterCursor :
            inputValue.slice(0, cursorPosition) + replacement + afterCursor;

        searchInput.value = newValue;

        // 更新光标位置
        nextTick(() => {
            const newPosition = cursorPosition - (lastToken?.length || 0) + replacement.length;
            kqlInput.value.setSelectionRange(newPosition, newPosition);
            kqlInput.value.focus();
        });
    }

    // 显示字段对应的运算符建议
    function showOperatorSuggestions(fieldName) {
        if (fieldConfigs.value[fieldName]) {
            const operators = fieldConfigs.value[fieldName].operators;
            suggestions.value = Object.entries(operators).map(([op, desc]) => ({
                type: 'operator',
                value: op,
                description: desc
            }));
            showSuggestions.value = true;
            currentSuggestionIndex.value = 0;
        }
    }

    // 处理输入
    function handleInput() {
        const textarea = kqlInput.value;
        // 自动调整高度
        textarea.style.height = 'auto';
        textarea.style.height = textarea.scrollHeight + 'px';
        
        const cursorPosition = textarea.selectionStart;
        const inputValue = searchInput.value;
        const beforeCursor = inputValue.slice(0, cursorPosition);
        const tokens = beforeCursor.split(/\s+/);
        const currentToken = tokens[tokens.length - 1];
        const prevToken = tokens[tokens.length - 2];

        // 重置建议列表
        suggestions.value = [];
        currentSuggestionIndex.value = 0;

        // 如果当前token为空，显示字段建议
        if (!currentToken || currentToken === '') {
            suggestions.value = Object.entries(fieldConfigs.value).map(([field, config]) => ({
                type: 'field',
                value: field,
                displayName: config.displayName,
                description: config.description
            }));
            showSuggestions.value = true;
            return;
        }

        // 如果前一个token是字段，显示该字段的运算符建议
        if (prevToken && fieldConfigs.value[prevToken]) {
            const operators = fieldConfigs.value[prevToken].operators;
            suggestions.value = Object.entries(operators)
                .filter(([op]) => op.toLowerCase().startsWith(currentToken.toLowerCase()))
                .map(([op, desc]) => ({
                    type: 'operator',
                    value: op,
                    description: desc
                }));
            showSuggestions.value = true;
            return;
        }

        // 搜索匹配的字段
        const matchedFields = Object.entries(fieldConfigs.value)
            .filter(([field, config]) => 
                field.toLowerCase().includes(currentToken.toLowerCase()) ||
                config.displayName.toLowerCase().includes(currentToken.toLowerCase())
            )
            .map(([field, config]) => ({
                type: 'field',
                value: field,
                displayName: config.displayName,
                description: config.description
            }));

        suggestions.value = matchedFields;
        showSuggestions.value = matchedFields.length > 0;
    }

    // 处理键盘事件
    function handleKeyDown(e) {
        if (!showSuggestions.value) {
            // 如果建议框没有显示，且按下回车键，执行搜索
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                onSearch();
                return;
            }
            return;
        }

        switch (e.key) {
            case 'ArrowDown':
                e.preventDefault();
                currentSuggestionIndex.value = (currentSuggestionIndex.value + 1) % suggestions.value.length;
                break;
            case 'ArrowUp':
                e.preventDefault();
                currentSuggestionIndex.value = (currentSuggestionIndex.value - 1 + suggestions.value.length) % suggestions.value.length;
                break;
            case 'Enter':
                e.preventDefault();
                if (suggestions.value.length > 0) {
                    selectSuggestion(suggestions.value[currentSuggestionIndex.value]);
                }
                break;
            case 'Escape':
                showSuggestions.value = false;
                break;
            case 'Tab':
                if (suggestions.value.length > 0) {
                    e.preventDefault();
                    selectSuggestion(suggestions.value[currentSuggestionIndex.value]);
                }
                break;
        }
    }

    // 处理焦点
    function handleFocus() {
        showSuggestions.value = true;
        handleInput();
    }

    // 处理失去焦点
    function handleBlur() {
        setTimeout(() => {
            showSuggestions.value = false;
        }, 200);
    }

    // 聚焦输入框
    function focusInput() {
        kqlInput.value?.focus();
    }

    // 获取日志类型的中文名称
    function getLogTypeText(value) {
        return logTypeMap[value] || '未知类型';
    }

    // 重置查询条件
    function resetQuery() {
        Object.assign(queryForm, queryFormState);
        timeRange.value = [dayjs().subtract(1, 'hour'), dayjs()]; // 重置为最近1小时
        searchInput.value = '';
        queryForm.pageNum = 1;
        queryForm.opnum = 1; // 确保日志类型也被重置为原始日志
        queryForm.indexName = ''; // 重置索引名称
        queryForm.aggregationFields = []; // 重置聚合字段
        queryData();
    }

    // 索引过滤函数
    function filterIndexOption(input, option) {
        return option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
    }

    // 搜索
    function onSearch() {
        // 更新查询参数
        queryForm.keyword = searchInput.value;
        queryForm.pageNum = 1;
        queryData();
    }

    // 解析KQL查询语句为ES查询条件
    function parseKqlToEsQuery(kqlString) {
        if (!kqlString) return null;

        try {
            // 标准化查询字符串，处理多个空格，但保留括号周围的空格
            const normalizedQuery = kqlString.trim()
                .replace(/\s+/g, ' ')
                .replace(/\(\s+/g, '(')
                .replace(/\s+\)/g, ')')
                .replace(/\s*\(\s*/g, ' ( ')
                .replace(/\s*\)\s*/g, ' ) ');
            
            console.log('标准化后的查询:', normalizedQuery);

            // 分词函数
            function tokenize(query) {
                const tokens = [];
                let currentToken = '';
                let inQuotes = false;
                let quoteChar = '';
                
                for (let i = 0; i < query.length; i++) {
                    const char = query[i];
                    
                    // 处理引号
                    if ((char === '"' || char === "'") && (i === 0 || query[i - 1] !== '\\')) {
                        if (!inQuotes) {
                            // 开始引号
                            if (currentToken) {
                                tokens.push(currentToken.trim());
                                currentToken = '';
                            }
                            inQuotes = true;
                            quoteChar = char;
                            currentToken = char;
                        } else if (char === quoteChar) {
                            // 结束引号
                            currentToken += char;
                            tokens.push(currentToken.trim());
                            currentToken = '';
                            inQuotes = false;
                        } else {
                            // 引号内的其他引号字符
                            currentToken += char;
                        }
                    }
                    // 处理括号
                    else if (!inQuotes && (char === '(' || char === ')')) {
                        if (currentToken) {
                            tokens.push(currentToken.trim());
                            currentToken = '';
                        }
                        tokens.push(char);
                    }
                    // 处理空格
                    else if (!inQuotes && char === ' ') {
                        if (currentToken) {
                            tokens.push(currentToken.trim());
                            currentToken = '';
                        }
                    }
                    // 其他字符
                    else {
                        currentToken += char;
                    }
                }
                
                if (currentToken) {
                    tokens.push(currentToken.trim());
                }
                
                return tokens.filter(t => t);
            }

            // 解析单个条件
            function parseCondition(expr) {
                try {
                    console.log('解析条件:', expr);
                    
                    // 使用更严格的正则表达式匹配，支持更多运算符和下划线字段名
                    const operatorPattern = 'not\\s+contains|contains|not\\s+in|in|==|!=|>=|<=|>|<|:|\\*|exists|not\\s+exists';
                    const match = expr.match(new RegExp(`^([\\w\\._-]+)\\s*(${operatorPattern})\\s*(.+)?$`));
                    
                    if (!match) {
                        console.log('条件不匹配正则:', expr);
                        return null;
                    }
                    
                    const [, field, operator, value] = match;
                    let cleanValue = value ? value.trim() : '';
                    
                    // 去除外层引号
                    if ((cleanValue.startsWith('"') && cleanValue.endsWith('"')) ||
                        (cleanValue.startsWith("'") && cleanValue.endsWith("'"))) {
                        cleanValue = cleanValue.slice(1, -1);
                    }

                    // 处理数组值 - 支持方括号语法和contains语法
                    if ((cleanValue.startsWith('[') && cleanValue.endsWith(']')) || 
                        (operator.includes('in'))) {
                        try {
                            let arrayValue;
                            if (cleanValue.startsWith('[') && cleanValue.endsWith(']')) {
                                // 处理[value1,value2,value3]格式
                            const arrayStr = cleanValue.slice(1, -1);
                                arrayValue = arrayStr.split(',').map(item => {
                                let val = item.trim();
                                if ((val.startsWith('"') && val.endsWith('"')) ||
                                    (val.startsWith("'") && val.endsWith("'"))) {
                                    val = val.slice(1, -1);
                                }
                                return val;
                            });
                            } else {
                                // 处理单个值作为数组
                                arrayValue = [cleanValue];
                            }
                            cleanValue = arrayValue;
                        } catch (e) {
                            console.error('解析数组值失败:', e);
                            return null;
                        }
                    }

                    console.log('解析结果:', { field, operator, cleanValue });

                    switch (operator.toLowerCase()) {
                        case ':':
                        case '==':
                            return {
                                match_phrase: {
                                    [field]: cleanValue
                                }
                            };
                        case '*':
                            return {
                                wildcard: {
                                    [field]: `*${cleanValue}*`
                                }
                            };
                        case '!=':
                            return { 
                                bool: { 
                                    must_not: [{ 
                                        match_phrase: { 
                                            [field]: cleanValue
                                        } 
                                    }] 
                                } 
                            };
                        case '>':
                            return { 
                                range: { 
                                    [field]: { gt: cleanValue } 
                                } 
                            };
                        case '>=':
                            return { 
                                range: { 
                                    [field]: { gte: cleanValue } 
                                } 
                            };
                        case '<':
                            return { 
                                range: { 
                                    [field]: { lt: cleanValue } 
                                } 
                            };
                        case '<=':
                            return { 
                                range: { 
                                    [field]: { lte: cleanValue } 
                                } 
                            };
                        case 'contains':
                            return {
                                wildcard: {
                                    [field]: `*${cleanValue}*`
                                }
                            };
                        case 'not contains':
                            return {
                                bool: {
                                    must_not: [{
                                        wildcard: {
                                            [field]: `*${cleanValue}*`
                                        }
                                    }]
                                }
                            };
                        case 'in':
                            return {
                                terms: {
                                    [field]: Array.isArray(cleanValue) ? cleanValue : [cleanValue]
                                }
                            };
                        case 'not in':
                            return {
                                bool: {
                                    must_not: [{
                                        terms: {
                                            [field]: Array.isArray(cleanValue) ? cleanValue : [cleanValue]
                                        }
                                    }]
                                }
                            };
                        case 'exists':
                            return {
                                exists: {
                                    field: field
                                }
                            };
                        case 'not exists':
                            return {
                                bool: {
                                    must_not: [{
                                        exists: {
                                            field: field
                                        }
                                    }]
                                }
                            };
                        default:
                            return {
                                match: {
                                    [field]: cleanValue
                                }
                            };
                    }
                } catch (error) {
                    console.error('解析单个条件失败:', error);
                    return null;
                }
            }

            // 解析表达式，支持括号
            function parseExpression(tokens, startIndex = 0) {
                console.log('开始解析表达式, tokens:', tokens.slice(startIndex));
                
                const conditions = [];
                let currentCondition = '';
                let i = startIndex;
                let currentOperator = 'AND';

                while (i < tokens.length) {
                    const token = tokens[i];
                    console.log('处理token:', token, '当前条件:', currentCondition);

                    if (token === '(') {
                        // 处理当前条件
                        if (currentCondition) {
                            const parsed = parseCondition(currentCondition.trim());
                            if (parsed) {
                                conditions.push({
                                    condition: parsed,
                                    operator: currentOperator
                                });
                            }
                            currentCondition = '';
                        }
                        
                        // 递归处理括号内的表达式
                        const { result, nextIndex } = parseExpression(tokens, i + 1);
                        if (result) {
                            conditions.push({
                                condition: result,
                                operator: currentOperator
                            });
                        }
                        i = nextIndex;
                    } else if (token === ')') {
                        // 处理最后一个条件
                        if (currentCondition) {
                            const parsed = parseCondition(currentCondition.trim());
                            if (parsed) {
                                conditions.push({
                                    condition: parsed,
                                    operator: currentOperator
                                });
                            }
                        }
                        return {
                            result: buildNestedQuery(conditions),
                            nextIndex: i + 1
                        };
                    } else if (token.toUpperCase() === 'OR' || token.toUpperCase() === 'AND') {
                        if (currentCondition) {
                            const parsed = parseCondition(currentCondition.trim());
                            if (parsed) {
                                conditions.push({
                                    condition: parsed,
                                    operator: currentOperator
                                });
                            }
                            currentCondition = '';
                        }
                        currentOperator = token.toUpperCase();
                    } else {
                        currentCondition += (currentCondition ? ' ' : '') + token;
                    }
                    i++;
                }

                // 处理最后一个条件
                if (currentCondition) {
                    const parsed = parseCondition(currentCondition.trim());
                    if (parsed) {
                        conditions.push({
                            condition: parsed,
                            operator: currentOperator
                        });
                    }
                }

                return {
                    result: buildNestedQuery(conditions),
                    nextIndex: i
                };
            }

            // 构建嵌套查询
            function buildNestedQuery(conditions) {
                if (!conditions.length) return null;
                if (conditions.length === 1) return conditions[0].condition;

                let currentQuery = null;
                let currentOperator = null;
                
                for (let i = 0; i < conditions.length; i++) {
                    const { condition, operator } = conditions[i];
                    
                    if (!currentQuery) {
                        currentQuery = condition;
                        currentOperator = operator;
                        continue;
                    }
                    
                    if (operator === 'AND') {
                        currentQuery = {
                    bool: {
                                must: [currentQuery, condition]
                            }
                        };
                    } else { // OR
                        // 如果前一个查询已经是OR组合，则添加到should数组中
                        if (currentQuery.bool && currentQuery.bool.should) {
                            currentQuery.bool.should.push(condition);
                        } else {
                            currentQuery = {
                                bool: {
                                    should: [currentQuery, condition],
                                    minimum_should_match: 1
                    }
                };
                        }
                    }
                }

                return currentQuery;
            }

            // 执行解析
            const tokens = tokenize(normalizedQuery);
            console.log('分词结果:', tokens);
            
            const { result } = parseExpression(tokens);
            console.log('最终生成的查询:', JSON.stringify(result, null, 2));
            
            return result;

        } catch (error) {
            console.error('KQL解析错误:', error);
            return null;
        }
    }

    // 查询数据
    async function queryData() {
        tableLoading.value = true;
        try {
            const queryParams = {
                pageNum: queryForm.pageNum,
                pageSize: queryForm.pageSize,
                indexName: 'event-base-*',
                sortField: '@timestamp',  // 固定使用@timestamp作为排序字段
                sortOrder: 'desc',
                eventTimeBegin: queryForm.eventTimeBegin,  // 添加时间范围参数
                eventTimeEnd: queryForm.eventTimeEnd,       // 添加时间范围参数
                opnum: queryForm.opnum, // 日志类型参数
                eventType: queryForm.eventType, // 添加事件类型参数
                severity: queryForm.severity, // 添加危险等级参数
                srcIp: queryForm.srcIp, // 添加源IP参数
                dstIp: queryForm.dstIp, // 添加目标IP参数
                threatCategory: queryForm.threatCategory, // 添加威胁分类参数
                keywords: queryForm.keywords, // 添加关键词参数
                protocol: queryForm.protocol, // 添加协议参数
                reqMethod: queryForm.reqMethod, // 添加请求方法参数
                reqStatus: queryForm.reqStatus, // 添加状态码参数
                reqHost: queryForm.reqHost, // 添加请求主机参数
                reqUserAgent: queryForm.reqUserAgent, // 添加User-Agent参数
                reqHeader: queryForm.reqHeader, // 添加请求头参数
                reqBody: queryForm.reqBody, // 添加请求体参数
                reqxff: queryForm.reqxff, // 添加X-Forwarded-For参数
                reqCookie: queryForm.reqCookie, // 添加Cookie参数
                queryString: queryForm.queryString, // 添加查询参数参数
                reqStartTime: queryForm.reqStartTime, // 添加请求开始时间参数
                reqEndTime: queryForm.reqEndTime, // 添加请求结束时间参数
                respHeader: queryForm.respHeader, // 添加返回头参数
                threatSignature: queryForm.threatSignature, // 添加威胁特征参数
                attackType: queryForm.attackType, // 添加攻击类型参数
                attackResult: queryForm.attackResult, // 添加攻击结果参数
                superType: queryForm.superType, // 添加攻击阶段参数
                payload: queryForm.payload, // 添加攻击载荷参数
                ruleAlertName: queryForm.ruleAlertName, // 添加规则名称参数
                ruleBatch: queryForm.ruleBatch, // 添加告警批次参数
                ruleAlertlevel: queryForm.ruleAlertlevel, // 添加威胁等级参数
                ruleAlertLinks: queryForm.ruleAlertLinks, // 添加攻击链参数
                ruleAlertResult: queryForm.ruleAlertResult, // 添加告警结果参数
                ruleAlertReason: queryForm.ruleAlertReason, // 添加告警描述参数
                ruleAlertDisposal: queryForm.ruleAlertDisposal, // 添加处置建议参数
                ruleCode: queryForm.ruleCode, // 添加规则代码参数
                whiteRuleEffect: queryForm.whiteRuleEffect, // 添加规则白名单参数
                deviceos: queryForm.deviceos, // 添加设备操作系统参数
                cType: queryForm.cType, // 添加连接方式参数
                rawLog: queryForm.rawLog, // 添加原始日志参数
                blocked: queryForm.blocked, // 添加安全设备处置结果参数
                action: queryForm.action, // 添加SOAR处置结果参数
                groupCount: queryForm.groupCount, // 添加分组数量参数
                groupKeys: queryForm.groupKeys, // 添加分组键值参数
                recname: queryForm.recname, // 添加记录名称参数
                aggregationFields: queryForm.aggregationFields, // 添加聚合字段参数
            };

            // 处理KQL查询
            if (queryForm.keyword) {
                const esQuery = parseKqlToEsQuery(queryForm.keyword);
                if (esQuery) {
                    // 添加调试日志
                    console.log('Generated ES Query:', JSON.stringify(esQuery, null, 2));
                    queryParams.esQuery = esQuery;
                }
            }

            let queryResult = await eventBaseEsApi.queryPage(queryParams);
            if (queryResult.ok) {
                tableData.value = queryResult.data.list || [];
                total.value = queryResult.data.total || 0;
            } else {
                message.error('查询失败：' + queryResult.msg);
                tableData.value = [];
                total.value = 0;
            }
        } catch (e) {
            smartSentry.captureError(e);
            message.error('查询异常，请检查ES连接状态: ' + e.message);
            tableData.value = [];
            total.value = 0;
        } finally {
            tableLoading.value = false;
        }
    }

    // 刷新数据
    async function refreshData() {
        queryForm.pageNum = 1;
        await queryData();
    }

    // 获取ES集群状态
    async function getClusterStatus() {
        try {
            const statusResult = await eventBaseEsApi.getClusterStatus();
            if (statusResult.ok) {
                message.success('ES连接正常');
            } else {
                message.warning('ES连接异常: ' + statusResult.msg);
            }
        } catch (e) {
            message.error('ES连接检查失败: ' + e.message);
        }
    }

    // 获取索引信息
    async function getIndexInfo() {
        try {
            const indexResult = await eventBaseEsApi.getIndexInfo();
            if (indexResult.ok) {
                message.info('索引信息: ' + JSON.stringify(indexResult.data));
            } else {
                message.warning('获取索引信息失败: ' + indexResult.msg);
            }
        } catch (e) {
            message.error('获取索引信息失败: ' + e.message);
        }
    }

    // 选择表格行
    function onSelectChange(selectedRowKeys) {
        selectedRowKeyList.value = selectedRowKeys;
    }

    // 显示详情
    const detailRef = ref();
    function showDetail(record) {
        console.log('showDetail called with record:', record);
        console.log('record, queryForm.opnum:', queryForm.opnum);
        console.log('queryForm.opnum type:', typeof queryForm.opnum);
        console.log('queryForm.opnum value:', JSON.stringify(queryForm.opnum));
        if (detailRef.value) {
            detailRef.value.show(record, queryForm.opnum);
        } else {
            console.error('detailRef.value is null or undefined');
        }
    }

    // SOAR 处置
    async function handleSoarDisposal(record) {
        try {
            // 设置加载状态
            if (record) {
                record.soarLoading = true;
            }
            
            // 准备SOAR处置参数
            const soarParams = {
                esId: record?.esId,
                srcIp: record?.srcIp
            };
            
            // 调用 SOAR 处置接口
            const response = await eventBaseEsApi.soarDisposal(soarParams);
            if (response.ok) {
                message.success('SOAR 处置成功');
                // 刷新列表
                await queryData();
            } else {
                message.error(response.msg || 'SOAR 处置失败');
            }
        } catch (e) {
            smartSentry.captureError(e);
            message.error('SOAR 处置异常：' + e.message);
        } finally {
            // 清除加载状态
            if (record) {
                record.soarLoading = false;
            }
        }
    }

    // 获取危险等级颜色
    function getSeverityColor(severity) {
        const colorMap = {
            '1': 'green',    // 低危
            '2': 'blue',     // 中危
            '3': 'orange',   // 高危
            '4': 'red',      // 严重
            '5': 'purple'    // 紧急
        };
        return colorMap[severity] || 'default';
    }

    // 获取危险等级文本
    function getSeverityText(severity) {
        const textMap = {
            '1': '低危',
            '2': '中危',
            '3': '高危',
            '4': '严重',
            '5': '紧急'
        };
        return textMap[severity] || severity;
    }

    // 获取HTTP状态码颜色
    function getStatusColor(status) {
        if (!status) return 'default';
        if (status >= 500) return 'red';
        if (status >= 400) return 'orange';
        if (status >= 300) return 'blue';
        if (status >= 200) return 'green';
        return 'default';
    }

    // 格式化时间戳
    function formatTimestamp(timestamp) {
        if (!timestamp) return '-';
        try {
            // 处理毫秒时间戳
            if (typeof timestamp === 'number') {
                return dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss');
            }
            // 处理ISO格式时间
            if (timestamp.includes('T')) {
                // 如果是带Z的UTC时间，需要转换为本地时间
                if (timestamp.endsWith('Z')) {
                    return dayjs(timestamp).local().format('YYYY-MM-DD HH:mm:ss');
                }
                return timestamp.replace('T', ' ').replace(/\.\d+Z?$/, '');
            }
            return timestamp;
        } catch (e) {
            return timestamp;
        }
    }

    // 格式化文件大小
    function formatFileSize(size) {
        if (!size) return '-';
        const num = parseFloat(size);
        if (isNaN(num)) return size;
        
        const units = ['B', 'KB', 'MB', 'GB', 'TB'];
        let unitIndex = 0;
        let value = num;
        
        while (value >= 1024 && unitIndex < units.length - 1) {
            value /= 1024;
            unitIndex++;
        }
        
        return `${value.toFixed(2)} ${units[unitIndex]}`;
    }

    // 获取HTTP方法颜色
    function getMethodColor(method) {
        const colorMap = {
            'GET': 'green',
            'POST': 'blue',
            'PUT': 'orange',
            'DELETE': 'red',
            'PATCH': 'purple',
            'HEAD': 'cyan',
            'OPTIONS': 'geekblue'
        };
        return colorMap[method?.toUpperCase()] || 'default';
    }

    // 添加事件分析方法
    function handleAnalyze(record) {
        // 实现事件分析逻辑
        if (record && record.eventId) {
            message.info('正在分析事件：' + record.eventId);
        } else {
            message.warning('事件信息不完整');
        }
    }

    // 过滤选项
    function filterOption(input, option) {
        return option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
        }

    // 在组件挂载时加载保存的列宽
    onMounted(() => {
        loadColumnWidths();
        getFieldConfigs();
        queryData();
    });

    // 添加聚合字段选项的计算属性
    const aggregationOptions = computed(() => {
        return Object.entries(fieldConfigs.value).map(([field, config]) => ({
            value: field,
            label: config.displayName || field
        }));
    });
</script>

<style scoped>
.smart-query-form {
    background: #fafafa;
    padding: 16px;
    margin-bottom: 16px;
    border-radius: 6px;
}

.smart-query-form-row {
    margin-bottom: 16px;
}

.smart-query-form-row:last-child {
    margin-bottom: 0;
}

.smart-table-btn-block {
    margin-bottom: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.smart-margin-left10 {
    margin-left: 10px;
}

.smart-table-operate {
    display: flex;
    gap: 8px;
}

.kql-search-container {
    background: #fff;
    padding: 16px;
    border-radius: 4px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.search-row {
    display: flex;
    align-items: center;
    gap: 16px;
}

.button-group {
    display: flex;
    gap: 8px;
    margin-left: auto;  /* 将按钮组推到右边 */
}

.kql-input-wrapper {
    position: relative;
    flex: 1;  /* 让输入框占据剩余空间 */
    min-width: 300px;  /* 设置最小宽度 */
}

.kql-input-container {
    width: 100%;
    border: 2px solid #ddd;
    border-radius: 4px;
    transition: all 0.3s;
    min-height: 40px;
    position: relative;
}

.kql-input-container:focus-within {
    border-color: #1890ff;
}

.kql-input {
    width: 100%;
    min-height: 40px;
    padding: 8px 12px;
    border: none;
    outline: none;
    font-size: 14px;
    background: transparent;
    resize: none;
    overflow: hidden;
    line-height: 1.5;
    font-family: monospace;
}

.kql-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    z-index: 1000;
    margin-top: 4px;
    max-height: 300px;
    overflow-y: auto;
}

.suggestions-list {
    padding: 4px 0;
}

.suggestion-item {
    padding: 8px 12px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
}

.suggestion-item.active {
    background-color: #e6f7ff;
}

.suggestion-item:hover {
    background-color: #f5f5f5;
}

.suggestion-icon {
    font-size: 16px;
    width: 20px;
}

.suggestion-text {
    flex: 1;
    color: #1890ff;
    font-weight: 500;
}

.suggestion-type {
    color: #666;
    font-size: 12px;
}

.no-suggestions {
    padding: 8px 12px;
    color: #999;
    text-align: center;
}

.time-range-container {
    margin-left: 16px;
}

.time-range-picker {
    width: 380px;
}

.ant-space {
    display: flex;
    align-items: center;
}

.time-range-footer {
    padding: 8px 12px;
    text-align: right;
}

.column-setting-content {
    width: 240px;  /* 增加宽度，让内容更宽松 */
    max-height: 500px;  /* 增加最大高度 */
}

.column-setting-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;  /* 增加内边距 */
    border-bottom: 1px solid #f0f0f0;  /* 添加分隔线 */
    margin-bottom: 8px;  /* 增加底部间距 */
}

.column-setting-header span {
    font-weight: 500;  /* 加粗标题 */
    color: #000000d9;  /* 加深标题颜色 */
}

.column-setting-list {
    max-height: 400px;  /* 增加列表高度 */
    overflow-y: auto;
    padding: 4px 8px;  /* 调整内边距 */
}

.column-item {
    padding: 8px 4px;  /* 增加内边距 */
    margin: 2px 0;  /* 调整外边距 */
    border-radius: 4px;  /* 添加圆角 */
    transition: all 0.3s;  /* 添加过渡效果 */
    cursor: pointer;
    display: flex;
    align-items: center;
}

.column-item:hover {
    background-color: #f5f5f5;  /* 添加悬停效果 */
}

.column-item .ant-checkbox-wrapper {
    width: 100%;  /* 让复选框占满整行 */
    display: flex;
    align-items: center;
}

.column-item .ant-checkbox {
    margin-right: 8px;  /* 调整复选框和文字的间距 */
}

.column-item .ant-checkbox + span {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #000000d9;  /* 加深文字颜色 */
}

:deep(.column-setting-popover) {
    .ant-popover-inner-content {
        padding: 0;  /* 移除默认内边距 */
    }

    .ant-popover-inner {
        border-radius: 8px;  /* 增加弹窗圆角 */
    }
}

/* 添加滚动条样式 */
.column-setting-list::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

.column-setting-list::-webkit-scrollbar-thumb {
    background: #0000001a;
    border-radius: 3px;
}

.column-setting-list::-webkit-scrollbar-track {
    background: transparent;
}
</style>

<style lang="less" scoped>
/* 日志类型选择器样式 */
.log-type-container {
    margin-left: 12px;
    display: flex;
    align-items: center;
}

.log-type-container .ant-select {
    min-width: 150px;
}

/* 索引选择器样式 */
.index-container {
    margin-left: 12px;
    display: flex;
    align-items: center;
}

.index-container .ant-select {
    min-width: 200px;
}

/* 优化表格样式 */
:deep(.ant-table) {
    .ant-table-thead > tr > th {
        background: #fafafa;
        font-weight: 600;
        color: #1f1f1f;
        padding: 8px;
    }

    .ant-table-tbody > tr > td {
        padding: 8px;
    }

    .ant-table-row:hover {
        background-color: #f5f5f5;
    }

    .ant-tag {
        margin: 0;
    }
}

/* 添加拖拽列样式 */
:deep(.ant-table) {
    .ant-table-thead > tr > th {
        position: relative;
        transition: background 0.3s;
        
        &::after {
            content: '';
            position: absolute;
            right: 0;
            top: 25%;
            width: 2px;
            height: 50%;
            background-color: transparent;
            cursor: col-resize;
            transition: background-color 0.3s;
        }
        
        &:hover::after {
            background-color: #1890ff;
        }
    }
    
    .resizing {
        cursor: col-resize;
        user-select: none;
        
        &::after {
            background-color: #1890ff;
        }
    }

    .ant-table-cell {
        transition: width 0.3s;
    }
}

/* 添加聚合字段选择器样式 */
.aggregation-container {
    margin-left: 12px;
    display: flex;
    align-items: center;
}

.aggregation-container .ant-select {
    min-width: 300px;
}
</style>


